调整ZONE

您所在的位置:网站首页 linux zone 调整ZONE

调整ZONE

2024-07-16 00:18| 来源: 网络整理| 查看: 265

问题场景:

arm64 开启了CONFIG_ZONE_DMA32,其区域默认是offset ~ offset+4G,其中offset一般为0,但是部分驱动无法完全访问到4G,需要限制DMA32区域的范围为0-2G。

qemu提取dts文件

尝试在qemu上调整一下ZONE_DMA32的大小,按照如下步骤导出qemu的dts文件: ./dtc -o dump.dts -O dts -I dtb dump.dtb qemu-system-aarch64 -machine virt,dumpdtb=dump.dtb cp dump.dtb linux/scripts/dtc/ cd linux/scripts/dtc/ make        这步如果内核已经编译过了,可以跳过。 ./dtc -o dump.dts -O dts -I dtb dump.dtb 生成的dts文件之后打开可见如下内存范围为0x40000000-0x80000000默认是1~2G内存范围, 359         memory { 360                 reg = ; 361                 device_type = "memory"; 362         }; 

通过qemu的cmdline可以传入例如8192m以调整内存大小。

内核调整DMA ZONE的关键节点

 对于x8664位系统: 

        x86_64 needs two ZONE_DMAs because it supports devices that are only able to do DMA         to the lower 16M but also 32 bit devices that  can only do DMA areas below 4G.

而对于arm64位系统:只有一个ZONE_DMA32 ,在zone_sizes_init会确定ZONE DMA32、ZONE_NORMAL的大小,DMA32的尽头就是NORMAL的开始。max_dma即 PFN_DOWN(arm64_dma_phys_limit),那么只要调整arm64_dma_phys_limit即可调整ZONE_DMA32的范围。

static void __init zone_sizes_init(unsigned long min, unsigned long max) { struct memblock_region *reg; unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES]; unsigned long max_dma = min; memset(zone_size, 0, sizeof(zone_size)); /* 4GB maximum for 32-bit only capable devices */ #ifdef CONFIG_ZONE_DMA32 max_dma = PFN_DOWN(arm64_dma_phys_limit); zone_size[ZONE_DMA32] = max_dma - min; #endif zone_size[ZONE_NORMAL] = max - max_dma; memcpy(zhole_size, zone_size, sizeof(zhole_size)); 。。。 }

通过cmdline来定制ZONE_DMA32的最大值,修改diff如下:

+static unsigned long dma_reset_end = 0; +static int __init dma_reset_end_setup(char *str) +{ + static int once; + if (once) + return 0; + once = 1; + dma_reset_end = memparse(str, &str); + printk("dma_reset_end=0x%lx\n", dma_reset_end); + return 0; +} /* * Return the maximum physical address for ZONE_DMA32 (DMA_BIT_MASK(32)). It * currently assumes that for memory starting above 4G, 32-bit devices will * use a DMA offset. */ static phys_addr_t __init max_zone_dma_phys(void) { + phys_addr_t max; phys_addr_t offset = memblock_start_of_DRAM() & GENMASK_ULL(63, 32); - return min(offset + (1ULL


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3